#include "STHashMap.h"
#include <iostream>


int STHashMap::STHash(const std::string & key)
{
    int hash = 0;
    for(int i = 0; i < key.size(); i++)
    {
        hash = (hash * 31 + key[i]) % HashSize;
    }
    return hash;


}

STHashMap::STHashMap(int HashSize)
{
    this->HashSize = HashSize;
    array = new Node *[this->HashSize];
    for(int i = 0; i < HashSize; i++)
    {
        array[i] = nullptr;
    }
}

STHashMap::~STHashMap()
{
}

void STHashMap::Insert(const std::string &key, ElementType value)
{
    Node * node = new Node(key,value);
    int index = STHash(key);
    if(array[index] = nullptr)
        array[index] = node;
    else
    {
        node->next = array[index];
        array[index]= node;
    }

}

ElementType *STHashMap::Get(const std::string &key)
{
    Node * node = array[STHash(key)];
    if(node = nullptr)
        return nullptr;
    else
    while(node != nullptr)
    {
        if(node->key == key)
            return &node->data;
        node = node->next;
    }
    return nullptr;
}

ElementType &STHashMap::operator[](const std::string &key)
{
    ElementType * data = Get(key);
    if(data)
        return * data;
    else
    {
        Insert(key,0);
        return *Get(key);
    }
}

void STHashMap::Remove(const std::string &key)
{
    for(int i = 0; i < HashSize; i++)
    {
        Node * node = array[i];
        if(node == nullptr)
            continue;
        if(node->key == key)
        {
            array[i] = node->next;
            delete node;
            return;
        }
        while(node->next != nullptr)
        {
            if(node->next->key == key)
            {
                Node * temp = node->next;
                node->next = node->next->next;
                delete temp;
                return;
            }
            node = node->next;
        }
    }
}

void STHashMap::show()
{
    
    for(int i = 0; i < HashSize; i++)
    {
        Node * node = array[i];
        while(node != nullptr)
        {
            std::cout<<" key:"<<node->key<<"| hash:"<<STHash(node->key)<<"| value:"<<node->data<<std::endl;
            node = node->next;
        }
    }
}

void STHashMap::showByKey()
{
    for(int i = 0; i < HashSize; i++)
    {
        Node * node = array[i];
        if(node == nullptr)
            return;
        else
        {
            std::cout<<node->data<<" ";
            node = node->next;
        }
        std::cout<<std::endl;

    }
}
